package com.novax.ex.activity.provider.controller.inner;

import com.novax.ex.activity.infrastructure.entity.IeoConfig;
import com.novax.ex.activity.infrastructure.entity.IeoContent;
import com.novax.ex.activity.infrastructure.entity.IeoCurrencyConfig;
import com.novax.ex.activity.infrastructure.entity.IeoStages;
import com.novax.ex.activity.infrastructure.entity.IeoVipLimit;
import com.novax.ex.activity.infrastructure.mapper.IeoConfigMapper;
import com.novax.ex.activity.infrastructure.mapper.IeoStagesMapper;
import com.novax.ex.activity.open.api.inner.IeoInnerConfigApi;
import com.novax.ex.activity.open.api.inner.IeoStagesApi;
import com.novax.ex.activity.open.model.query.IeoConfigQuery;
import com.novax.ex.activity.open.model.query.OrderInnerQuery;
import com.novax.ex.activity.open.model.request.IeoConfigRequest;
import com.novax.ex.activity.open.model.request.IeoContentRequest;
import com.novax.ex.activity.open.model.request.IeoCurrencyRequest;
import com.novax.ex.activity.open.model.request.IeoStagesRequest;
import com.novax.ex.activity.open.model.request.IeoVipRequest;
import com.novax.ex.activity.open.model.response.IeoConfigResponse;
import com.novax.ex.activity.open.model.response.IeoContentResponse;
import com.novax.ex.activity.open.model.response.IeoCurrencyConfigResponse;
import com.novax.ex.activity.open.model.response.IeoStagesResponse;
import com.novax.ex.activity.open.model.response.IeoSubscribeCopyResponse;
import com.novax.ex.activity.open.model.response.IeoSubscribeResponse;
import com.novax.ex.activity.open.model.response.IeoVipLimitResponse;
import com.novax.ex.activity.provider.controller.BaseActivityController;
import com.novax.ex.activity.provider.handler.provider.IeoProviderService;
import com.novax.ex.activity.provider.service.IeoConfigService;
import com.novax.ex.activity.provider.service.IeoContentService;
import com.novax.ex.activity.provider.service.IeoCurrencyConfigService;
import com.novax.ex.activity.provider.service.IeoOrderService;
import com.novax.ex.activity.provider.service.IeoStagesService;
import com.novax.ex.activity.provider.service.IeoVipLimitService;
import com.novax.ex.common.base.BaseEntity;
import com.novax.ex.common.constant.InternationalCode;
import com.novax.ex.common.results.ReturnResult;
import com.novax.ex.common.util.CopyUtils;
import com.novax.ex.common.util.DateUtil;
import com.novax.ex.common.util.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RestController;

import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @Description ieo 分期配置Controller
 * @Author chenxi
 * @Date 2022/12/01/18:09
 */
@Slf4j
@RestController
public class IeoStagesController extends BaseActivityController implements IeoStagesApi {

    @Resource
    private IeoStagesService ieoStagesService;

    @Resource
    private IeoConfigService ieoConfigService;

    @Override
    public ReturnResult<?> stages(String language, List<IeoStagesRequest> ieoStagesRequestList, Long ieoId, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ReturnResult.fail(getInternational(language, InternationalCode.LACK_VALUE));
        }

        IeoConfig ieoConfig = ieoConfigService.find(ieoId);
        if(Objects.isNull(ieoConfig)){
            return ReturnResult.fail(getInternational(language, InternationalCode.NOT_FOUND));
        }

        Integer unfreeze = ieoConfig.getUnfreeze();
        if(unfreeze >= 2){
            return ReturnResult.fail(getInternational(language, InternationalCode.CHANG_UNLOCK));
        }

        // 如果传空, 则删除所有分期配置
        if(ieoStagesRequestList.isEmpty()){
            ieoConfig.setStage(0);
            boolean flag = ieoStagesService.deleteByIeoId(ieoId, ieoConfig);
            if(flag){
                return ReturnResult.success(getInternational(language, InternationalCode.OPERATION_SUCCESS));
            } else {
                return ReturnResult.fail(getInternational(language, InternationalCode.OPERATION_ERROR));
            }
        }

        // 校验 发放百分比 是否大于0, 最多一位小数,
        boolean isAmountValid = ieoStagesRequestList.stream()
            .allMatch(item -> item.getAmount().compareTo(BigDecimal.ZERO) > 0
                              && item.getAmount().compareTo(new BigDecimal(100)) <= 0
                              && item.getAmount().scale() <= 1);

        if(!isAmountValid){
            return ReturnResult.fail(getInternational(language, InternationalCode.DISTRIBUTE_PERCENTAGE_INCORRECT));
        }
        // 总和等于100
        boolean isSumValid = ieoStagesRequestList.stream()
                                 .map(IeoStagesRequest::getAmount)
                                 .reduce(BigDecimal.ZERO, BigDecimal::add)
                                 .compareTo(new BigDecimal(100)) == 0;

        if(!isSumValid){
            return ReturnResult.fail(getInternational(language, InternationalCode.DISTRIBUTE_PERCENTAGE_INCORRECT));
        }

        // 解锁时间必须大于结束时间
        Date endTime = ieoConfig.getEndTime();
        boolean unlockAfterEnd = ieoStagesRequestList.stream()
            .allMatch(request -> request.getUnlockTime().after(endTime));

        if(!unlockAfterEnd){
            return ReturnResult.fail(getInternational(language, InternationalCode.ERROR_UNLOCK_TIME_PARAPET));
        }

        // 解锁时间从小到大
        boolean isSorted = IntStream.range(0, ieoStagesRequestList.size() - 1)
            .allMatch(i -> ieoStagesRequestList.get(i).getUnlockTime()
                               .compareTo(ieoStagesRequestList.get(i + 1).getUnlockTime()) <= 0);

        if(!isSorted){
            return ReturnResult.fail(getInternational(language, InternationalCode.ERROR_UNLOCK_TIME_PARAPET));
        }

        List<IeoStages> ieoStagesList = CopyUtils.copyList(ieoStagesRequestList, IeoStages.class);
        ieoStagesList.forEach(s -> {
            s.setIeoId(ieoId);
            s.setState(0);
        });

        ieoConfig.setStage(1);
        // 如果配置了分期则IEO解锁时间为分期第一期时间
        ieoConfig.setUnlockTime(ieoStagesList.get(0).getUnlockTime());
        boolean flag = ieoStagesService.addStagesConfig(ieoId, ieoStagesList, ieoConfig);
        if(flag){
            return ReturnResult.success(getInternational(language, InternationalCode.OPERATION_SUCCESS));
        } else {
            return ReturnResult.fail(getInternational(language, InternationalCode.OPERATION_ERROR));
        }

    }


    @Override
    public ReturnResult<List<IeoStagesResponse>> query(String language, Long ieoId) {
        List<IeoStagesResponse> list = CopyUtils.copyList(ieoStagesService.findListByIeoId(ieoId), IeoStagesResponse.class);
        return ReturnResult.success(getInternational(language, InternationalCode.QUERY_SUCCESS), list);
    }

}
